#pragma once 
#include <iostream>
#include <string>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <vector>

#define MYSELF


// 协议定制（所写协议为不完善的，目的在于理解什么是协议，协议的大体框架）
// 理解序列化和反序列化 








namespace myself
{

//SPACE为序列化相关
#define SPACE " "
#define SPACE_LEN strlen(SPACE)
//SEP为报文封装相关
#define SEP "X"
#define SEP_LEN strlen(SEP) 
// 为什么不用sizeof ，sizeof计算”/r/n“计算出错误结果，结果1 


//此函数为后续添加和Response 以及 Request中的方法不一样，没有任何关系
//buffer 为输入输出型参数 
//out为输出型参数
//buffer被读走时，要将读走的部分从buffer中删除。 
void SpliteMessage(std::string& buffer, std::vector<std::string>* out)
{
    while (true) // 可能一次读取到的不只一个报文
    {
        auto pos = buffer.find(SEP);
        if(std::string::npos == pos)
        {
            //代表无剩余内容或剩余报文不完整
            break; 
        }
        std::string message = buffer.substr(0, pos);
        buffer.erase(0, pos +SEP_LEN);
        out->push_back(message);
    }
    
}


std::string Encode(std::string& s )
{
    return s + SEP ; 
}









    class Request
    {
    public:
        
        int _x ;
        int _y ;
        char _op ;

    public:

        //将结构体中的内容序列化为字符串
        std::string Serialize()
        {
#ifdef MYSELF
            std::string str ; 
            str = std::to_string(_x);
            str += SPACE ; 
            str += _op ; 
            str += SPACE ;
            str += std::to_string(_y);
            return str ;
#else
#endif 
        }

        //将字符串的内容反序列化存入结构体中
        bool Deserialized(const std::string& str)
        {
#ifdef MYSELF
            //用户输入的格式是”_x + _y“
            std::size_t left = str.find(SPACE) ;
            if(left == std::string::npos )
            {
                return false ; 
            }
            std::size_t right = str.rfind(SPACE);
            if(right == std::string::npos )
            {
                return false ;
            }

            _x =  atoi(str.substr(0,left).c_str());
            _y =  atoi(str.substr(right + SPACE_LEN).c_str());
            if(left + SPACE_LEN > str.size())
            {
                return false ;
            }
            else
            {
                _op = str[left + SPACE_LEN];
            }
            return true; 
#else
#endif
        }

public:

        Request()
        {

        }
 
        Request(int x , int y , char op)
            :_x(x)
            ,_y(y)
            ,_op(op)
        {

        }

        ~Request()
        {

        }

    } ;









    class Response
    {
    public:
        
        int _result ; // 结果
        
        int _code   ; // 状态
        int _x ;
        int _y ;
        char _op;

    public:

        Response()
        {

        }
        
        Response(int result , int code , int x , int y , char op)
            :_result(result)
            ,_code(code)
            ,_x(x)
            ,_y(y)
            ,_op(op)
        {

        }



    public:

        std::string Serialize()
        {
#ifdef MYSELF
            std::string s ; 
            s = std::to_string(_code);
            s += SPACE ;
            s += std::to_string(_result);
            return s ;
#else
#endif
        }


        bool Deserialized(const std::string& str)
        {
#ifdef MYSELF
            std::size_t pos = str.find(SPACE);
            if(pos == std::string::npos )
            {
                return false ; 
            }
            _code = atoi(str.substr(0,pos).c_str());
            _result = atoi(str.substr(pos + SPACE_LEN).c_str());
            return true ;
#else
#endif
        }

        

    } ;
 
    
        //该函数不是最终的接收，out是一个输出型参数:
        bool Recv(int sock , std::string* out )
        {
            char buffer[1024];
            ssize_t s = recv(sock, buffer, sizeof (buffer) - 1, 0);
            if(s > 0)
            {
                buffer[s] = 0 ;
                *out += buffer ;
            }
            else if(s == 0)
            {   
                // quit
                return false ;
            }
            else 
            { 
                //error
                return false ;
            }

            return true ; 
        }

        void Send(int sock , const std::string& str)
        {
            int n = send(sock, str.c_str(), str.size(), 0); // ? ? ? ? 
            if(n < 9)
            {
                std::cout << "send error " << std::endl ; 
            }
        }

        //读到报文完整关键：
        //一次解析一个报文
        // 即使对1个半报文，也可以解析出一个完整报文，留下另外半个，等待补全后再次解析。
        std::string Decode(std::string& buffer)
        {
            std::size_t pos = buffer.find(SEP);
            if(pos == std::string::npos)
            {
                return "";
            }
            int size = atoi(buffer.substr(0,pos).c_str());
            int surplus = buffer.size() - pos - 2*SEP_LEN ; // 正文长度.
            if(surplus >= size) // 至少有一个完整报文时
            {
                buffer.erase(0, pos+SEP_LEN);
                std::string s = buffer.substr(0, size);
                buffer.erase(0, size + SEP_LEN);
                return s ; 
            }
            else
            {
                return "";
            }
        }

        //添加报文
        /*std::string Encode(std::string& s)
        {
            std::string new_package = std::to_string(s.size());
            new_package += SEP; 
            new_package += s ;
            new_package += SEP ;
            return new_package ; 
        }*/
}









